<template>
  <div class="section_block" ref="section">
    <div class="publish_block">
      <div class="new_topic" v-show="!scheduleShow">
        <div class="topic_selector" @click.stop="() => {}">
          <div class="topic_selector_desk">
            <div class="topic_selector_search">
              <div class="topic_search">
                <div
                  class="topic_search_popover"
                  :class="topicSearchShow ? 'active' : ''"
                >
                  <div class="topic_search_input">
                    <i class="iconfont icon-sousuo" v-if="topicSearchShow"></i>
                    <i class="iconfont icon-label" v-else></i>
                    <span
                      class="topic_search_input_text"
                      :style="[topicSearchShow ? { display: 'none' } : {}]"
                      @click.stop="openTopicSearch"
                      >选择话题</span
                    >
                    <input
                      type="text"
                      class="topic_search_input_inner"
                      placeholder="搜索话题"
                      :style="[!topicSearchShow ? { display: 'none' } : {}]"
                      placeholder-style="color:#d9d9d9"
                      @input="searchTopic"
                    />
                  </div>
                  <div
                    class="topic_search_result"
                    :style="[!topicSearchShow ? { display: 'none' } : {}]"
                  >
                    <div
                      class="topic_search_list"
                      v-for="item in topicList"
                      @click="selectTopic(item)"
                      :key="item.id"
                    >
                      <div class="topic_item cloud" :title="item.topicname">
                        <div
                          class="topic_item_cloud"
                          :class="
                            topic && topic.id == item.id ? 'selected' : ''
                          "
                        >
                          <i class="iconfont icon-label"></i>
                          <div class="topic_item_cloud_info">
                            <div class="topic_item_cloud_title">
                              <div
                                class="topic_item_cloud_name"
                                :class="
                                  topic && topic.id == item.id ? 'selected' : ''
                                "
                              >
                                {{ item.topicname }}
                              </div>
                            </div>
                            <div class="topic_item_cloud_desc">
                              {{ item.topicdesc }}
                            </div>
                          </div>
                        </div>
                      </div>
                    </div>
                  </div>
                </div>
              </div>
            </div>
            <div class="topic_selector_rcmd">
              <div class="topic_selector_rcmd_default">
                <div
                  class="topic_item stela"
                  :title="item.topicname"
                  v-for="(item, index) in topicRcmdList"
                  v-if="index < 3"
                  @click="selectTopic(item)"
                >
                  <div class="topic_item_stela">
                    <i class="iconfont icon-label"></i>
                    <span class="topic_item_stela_name">
                      <span>{{ item.topicname }}</span>
                    </span>
                  </div>
                </div>
              </div>
              <div
                class="topic_selector_rcmd_more"
                v-show="topicRcmdList.length > 3"
              >
                <div class="topic_rcmd_more">
                  <div
                    class="topic_rcmd_more_popover"
                    @mouseenter="topicRcmdActive = true"
                    @mouseleave="topicRcmdActive = false"
                    :class="topicRcmdActive && !topic ? 'hover' : ''"
                  >
                    <div class="topic_rcmd_more_bar">
                      <div class="topic_rcmd_more_action">
                        <i class="iconfont icon-zhankai"></i>
                      </div>
                      <div class="topic_rcmd_more_text">更多推荐话题</div>
                    </div>
                    <div
                      class="topic_rcmd_more_item"
                      v-for="(item, index) in topicRcmdList"
                      v-if="index > 2"
                      @click="selectTopic(item)"
                    >
                      <div class="topic_item cloud" :title="item.topicname">
                        <div class="topic_item_cloud">
                          <i class="iconfont icon-label"></i>
                          <div class="topic_item_cloud_info">
                            <div class="topic_item_cloud_info_title">
                              <div class="topic_item_cloud_info_name">
                                {{ item.topicname }}
                              </div>
                            </div>
                          </div>
                        </div>
                      </div>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
          <transition name="bulletin">
            <div class="topic_selector_bulletin" v-if="topic">
              <div
                class="topic_selector_bulletin_item"
                @click="openTopicSearch"
              >
                <div class="topic_item normal" :title="topic.topicname">
                  <div class="topic_item_normal">
                    <i class="iconfont icon-label"></i>
                    <span class="topic_item_normal_name">{{
                      topic.topicname
                    }}</span>
                  </div>
                </div>
              </div>
              <div class="topic_selector_bulletin_clear" @click="clearTopic">
                <i class="iconfont icon-guanbi"></i>
              </div>
            </div>
          </transition>
        </div>
      </div>
      <div class="editorbox">
        <div
          class="editor"
          :class="contentLen || inputType ? '' : 'placeholder-shown'"
          placeholder="有什么想和大家分享的?"
        >
          <div
            contenteditable="true"
            id="editor"
            class="core_style"
            @input="change"
            @compositionend="compositionend"
            @compositionstart="compositionstart"
            @blur="inputblur"
            @click="inputclick"
            @keyup="inputkeyup"
            ref="inputbox"
            spellcheck="false"
            @click.stop="() => {}"
          >
            <!-- &zwj;{{ "\n" }} -->
          </div>
        </div>
        <div class="publish_tip">
          <div v-if="publishTipActive == 1">动态发布后将关闭评论区</div>
          <div v-else-if="publishTipActive == 2">
            动态发布后评论内容在经过你的精选后向所有用户展示
          </div>
        </div>
        <transition name="schedule">
          <Schedule
            v-show="scheduleShow"
            :maxRegularTime="15"
            @send="sendScheduleContent"
          />
        </transition>
        <div class="attach_card" v-if="reserveContent">
          <div class="shop_panel">
            <div class="shop_list reserve">
              <div class="shop_desc reserve">
                <a class="desc_box" draggable="false">
                  <div class="title multi_line">
                    直播预约：{{ reserveContent.reserveTitle }}
                  </div>
                  <div class="sub_title reserve">
                    <span
                      >{{ reserveContent.reserveDate | dateFilter }}
                      {{ reserveContent.reserveHour | hourFilter }}:{{
                        reserveContent.reserveMinute | minuteFilter
                      }}
                      直播</span
                    >
                  </div>
                </a>
              </div>
              <dir class="delete_btn" @click="deleteReserve">
                <i class="iconfont icon-guanbi"></i>
              </dir>
            </div>
          </div>
        </div>
      </div>
      <div class="toolbar">
        <div class="toolbar_box">
          <div class="toolbar_item emoji_box">
            <div class="box_toggle" @click.stop="openEmoji" title="表情">
              <i
                class="iconfont icon-biaoqing"
                :class="emojiBoxShow ? 'on' : ''"
              ></i>
            </div>
            <!-- 表情展示框 -->
            <transition name="emojiBox">
              <EmojiBox
                v-if="emojiBoxShow"
                @inputEmoji="inputEmoji"
                @close="closeEmoji"
              />
            </transition>
          </div>
          <div class="toolbar_item pic_box">
            <div class="box_toggle" @click="openUploadBox" title="上传图片">
              <i
                class="iconfont icon-tupian"
                :class="uploadShow ? 'on' : ''"
              ></i>
            </div>
            <!-- 图片上传 -->
            <UploadImage
              v-if="uploadShow"
              :uploadImgMaxNum="9"
              :allowDrag="true"
              :allowOpenUpload="false"
              @close="closeUploadBox"
              @send="sendUploadImageList"
              ref="uploadImage"
            />
          </div>
          <div class="toolbar_item at_icon">
            <div class="box_toggle" @click="openAt">
              <i class="iconfont icon-aite"></i>
            </div>
            <AtPopup v-if="atShow" :left="atPopupLeft" :top="atPopupTop" />
          </div>
          <div
            class="toolbar_item schedule_box"
            v-show="!scheduleShow && !reserveContent"
          >
            <div class="box_toggle" @click="openVote" title="发起投票">
              <i
                class="iconfont icon-toupiao"
                :class="voteShow ? 'on' : ''"
              ></i>
            </div>
            <transition name="vote">
              <Vote
                v-if="voteShow"
                @close="closeVote"
                :voteContent="voteContent"
                @submit="saveVote"
              />
            </transition>
          </div>
          <div
            class="toolbar_item vote_box"
            v-show="
              !voteShow && !voteContent && !reserveShow && !reserveContent
            "
          >
            <div
              class="box_toggle"
              @click="scheduleShow = !scheduleShow"
              title="定时发布"
            >
              <i
                class="iconfont icon-miaobiao"
                :class="scheduleShow ? 'on' : ''"
              ></i>
            </div>
          </div>
          <div class="toolbar_item reserve_box" v-show="!scheduleShow">
            <div class="box_toggle" title="直播预约" @click="openReserve">
              <i
                class="iconfont icon-ic_zhiboyuyue"
                :class="reserveContent ? 'on' : ''"
              ></i>
            </div>
            <transition name="layer">
              <Reserve
                @close="closeReserve"
                @save="saveReserve"
                v-if="reserveShow"
                :reserveContent="reserveContent"
              />
            </transition>
          </div>
        </div>
        <div class="publish_launcher">
          <span
            class="indicator"
            title="全角字符计数为1半角字符计数为0.5，不足1时记为1"
            v-show="contentLen > 0"
            >{{ contentLen }}</span
          >
          <div class="comment_setting" @click="() => {}">
            <div class="comment_setting_btn" @click.stop="openSettingPanel">
              <span>{{ settings_panel_option[publishTipActive] }}</span>
              <i
                class="iconfont icon-zhankai"
                :class="settingPanelShow ? 'active' : ''"
              ></i>
            </div>
            <transition name="settings">
              <div class="settings_panel" v-show="settingPanelShow">
                <div
                  class="settings_panel_option"
                  :class="publishTipActive == index ? 'active' : ''"
                  v-for="(item, index) in settings_panel_option"
                  @click.stop="publishTipActive = index"
                >
                  {{ item }}
                </div>
              </div>
            </transition>
          </div>
          <div class="article_pub_btn_box" v-show="false">
            <button class="to_article">转为专栏</button>
          </div>
          <button
            class="publish_btn"
            :class="contentLen == 0 ? 'disable' : ''"
            :disabled="contentLen == 0"
            @click="sumbit"
          >
            发布
          </button>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import EMOJILIST from "../../static/emoji.js";
import UploadImage from "./component/uploadImage";
import EmojiBox from "./component/emojiBox";
import AtPopup from "./component/atPopup";
import Vote from "./component/vote";
import Schedule from "./component/schedule";
import Reserve from "./component/reserve.vue";
export default {
  components: {
    UploadImage,
    EmojiBox,
    AtPopup,
    Vote,
    Schedule,
    Reserve,
  },
  data() {
    return {
      $section: null,
      sectionOffsetLeft: 0,
      sectionOffsetTop: 0,
      emojiList: EMOJILIST,
      $inputbox: null,
      inputType: false, //true输入法输入,false普通输入
      content: "",
      contentLen: 0,
      emojiBoxShow: false,
      getContent: "", //动态字符串
      uploadShow: false, //
      uploadImgList: [], //

      topicSearchShow: false, //打开话题搜索
      topicList: [],
      topic: null,
      topicRcmdActive: false,
      topicRcmdList: [], //动态输入框动态查询结果

      atShow: false,
      atPopupLeft: 0,
      atPopupTop: 0,

      settingPanelShow: false, //打开动态评论设置
      timeOut_settingPanel: null, //动态评论设置定时器
      className_settings_panel: "", //动画class名
      settings_panel_option: ["允许评论", "关闭评论", "精选评论"],
      publishTipActive: 0,

      voteShow: false,
      voteContent: null, //投票内容对象
      $voteTitle: null, //投票标题节点对象
      hasVote: false, //判断投票是否存在

      scheduleShow: false,

      reserveShow: false,
      reserveContent: null, //直播预约内容

      docCB: null,
    };
  },
  mounted() {
    this.$section = this.$refs.section;
    this.sectionOffsetLeft =
      this.$section.offsetLeft + this.$section.parentNode.parentNode.offsetLeft;
    this.sectionOffsetTop =
      this.$section.offsetTop + this.$section.parentNode.parentNode.offsetTop;
    this.$inputbox = this.$refs.inputbox;
    this.inputBoxFocus();
    // 禁止拖拽
    this.$inputbox.ondragstart = function () {
      return false;
    };
    this.getUserSelect();
    this.$inputbox.addEventListener("keydown", (event) => {
      if (
        this.atShow &&
        (event.key == "ArrowDown" ||
          event.key == "ArrowUp" ||
          event.key == "Enter")
      ) {
        event.preventDefault();
      }
    });
  },
  methods: {
    // 节点事件监听
    domAddEventListen(dom, type, cb = () => {}) {
      if (!dom) {
        throw new Error("请传入节点对象");
      }
      if (!type) {
        throw new Error("请传入监听类型");
      }
      dom.removeEventListener(type, cb);
      dom.addEventListener(type, cb);
    },
    // 打开直播预约
    openReserve() {
      this.reserveShow = true;
    },
    // 关闭直播预约
    closeReserve() {
      this.reserveShow = false;
    },
    // 发起直播预约
    saveReserve(data) {
      this.reserveContent = data;
      this.closeReserve();
    },
    // 删除直播预约
    deleteReserve() {
      this.reserveContent = null;
    },
    // 打开投票
    openVote() {
      this.voteShow = true;
    },
    // 关闭投票
    closeVote() {
      this.voteShow = false;
    },
    // 发起投票或者修改投票内容
    saveVote(voteContent, type = "save") {
      this.voteContent = voteContent;
      let { voteTitle } = voteContent;
      if (type == "save") {
        this.inputBoxFocus();
        let { lastChild } = this.$inputbox;
        if (lastChild && lastChild.nodeName == "#text") {
          if (lastChild.textContent && lastChild.textContent.length >= 2) {
            let endstr = lastChild.textContent.slice(-2);
            if (endstr !== "\n\n" && /\n$/.test(endstr)) {
              lastChild.textContent = lastChild.textContent.replace(/\n$/, "");
            }
          }
        }
        let docF = document.createDocumentFragment();
        let startNode = document.createTextNode("你发起了一个投票 ");
        let iconNode = document.createElement("i");
        let endNode = document.createTextNode("\n");
        iconNode.style.position = `relative`;
        iconNode.style.top = `-1px`;
        iconNode.style["margin-left"] = `2px`;
        iconNode.style[`margin-right`] = `2px`;
        iconNode.className = `vote_icon vote_btn`;
        let voteTitleNode = document.createTextNode(`​${voteTitle}`);
        this.$voteTitle = voteTitleNode;
        let linkNode = document.createElement("span");
        linkNode.className = `dynamic_link`;
        linkNode.style.cursor = `pointer`;
        linkNode.style.color = `rgb(0, 161, 214)`;
        linkNode.contentEditable = `false`;
        linkNode.appendChild(iconNode);
        linkNode.appendChild(voteTitleNode);
        this.domAddEventListen(linkNode, "click", this.openVote);
        docF.appendChild(startNode);
        docF.appendChild(linkNode);
        docF.appendChild(endNode);
        this.$inputbox.appendChild(docF);
        this.$inputbox.normalize();
        this.setRange(endNode, 0);
      } else if (type == "update") {
        this.$voteTitle.textContent = `​${voteTitle}`;
      }
      this.$nextTick(() => {
        this.content = this.$inputbox.innerHTML;
        this.contentLen = this.countLen();
      });
    },
    // 打开@
    openAt() {
      // this.atShow = true;
      this.inputBoxFocus();
      let node = document.createTextNode("@");
      let range = getSelection().getRangeAt(0);
      // 判断当前文本节点前是否为单独\n，是则删除
      let { startContainer, startOffset } = range;
      let endchart;
      if (startContainer.textContent.length >= 2) {
        endchart = startContainer.textContent.slice(
          startOffset - 1,
          startOffset + 1
        );
        if (!(endchart == "\n\n") && /\n$/.test(endchart)) {
          startContainer.textContent = startContainer.textContent.replace(
            /\n$/,
            ""
          );
          range = this.setRange(startContainer, startOffset).getRangeAt(0);
        }
      }
      range.insertNode(node);
      range.collapse(false);
      this.$nextTick(() => {
        this.content = this.$inputbox.innerHTML;
        this.contentLen = this.countLen();
      });
      this.setRange(node, 1);
      this.$inputbox.normalize();
      this.getAtPosition();
    },
    // 关闭@
    closeAt() {
      this.atShow = false;
    },
    // 打开话题查询
    openTopicSearch() {
      this.topicSearchShow = true;
      this.getTopic();
      this.documentAddEventListen("click", () => {
        this.topicSearchShow = false;
      });
    },
    // 搜索相关话题
    searchTopic(e) {
      let { value } = e.detail;
      this.getTopic(value);
    },
    // 获取相关话题
    getTopic(value) {
      this.topicList = [
        {
          id: "1",
          topicname: "开年美食大狂欢1",
          topicdesc: "2.2亿浏览·55.6万讨论",
        },
        {
          id: "2",
          topicname: "开年美食大狂欢2",
          topicdesc: "2.2亿浏览·55.6万讨论",
        },
        {
          id: "3",
          topicname: "开年美食大狂欢3",
          topicdesc: "2.2亿浏览·55.6万讨论",
        },
        {
          id: "4",
          topicname: "开年美食大狂欢4",
          topicdesc: "2.2亿浏览·55.6万讨论",
        },
        {
          id: "5",
          topicname: "开年美食大狂欢5",
          topicdesc: "2.2亿浏览·55.6万讨论",
        },
        {
          id: "6",
          topicname: "开年美食大狂欢6",
          topicdesc: "2.2亿浏览·55.6万讨论",
        },
      ];
    },
    getCloudTopic(value) {
      if (this.content.indexOf("年度") > -1) {
        this.topicRcmdList = [
          {
            id: "1",
            topicname: "年度听歌总结",
          },
          {
            id: "2",
            topicname: "up主荣誉年报",
          },
          {
            id: "3",
            topicname: "时尚年度爱品",
          },
          {
            id: "4",
            topicname: "年度好物盘点",
          },
          {
            id: "4",
            topicname: "我的年度报告",
          },
        ];
      } else {
        this.topicRcmdList = [];
      }
    },
    //选择话题
    selectTopic(item) {
      this.topic = item;
      this.topicSearchShow = false;
    },
    // 删除话题
    clearTopic() {
      this.topic = null;
    },
    // 打开上传图片
    openUploadBox() {
      if (this.uploadShow == true) return;
      this.uploadShow = true;
    },
    closeUploadBox() {
      this.uploadShow = false;
      this.uploadImgList = [];
    },
    // 打开动态评论设置
    openSettingPanel() {
      if (this.settingPanelShow) {
        this.documentRemoveEventListen("click", this.docCB);
        this.closeSettingPanel();
        return;
      }
      this.settingPanelShow = true;
      this.documentAddEventListen("click", this.closeSettingPanel);
    },
    // 关闭动态评论设置
    closeSettingPanel() {
      this.settingPanelShow = false;
    },
    // 文档单次监听
    documentAddEventListen(type, cb) {
      this.docCB = () => {
        cb();
        document.documentElement.removeEventListener(type, this.docCB);
      };
      document.documentElement.addEventListener(type, this.docCB);
    },
    // 文档取消单击监听
    documentRemoveEventListen(type, cb) {
      if (cb) document.documentElement.removeEventListener(type, cb);
    },
    //触发获取图片数组事件
    getUploadImageList() {
      this.$bus.$emit("getUploadImageList");
    },
    // 接收图片数据
    sendUploadImageList(data) {
      console.log(data, "图片数据");
    },
    // 触发获取定时发布数据
    getScheduleContent() {
      this.$bus.$emit("getScheduleContent");
    },
    // 接收定时发布数据
    sendScheduleContent(data) {
      console.log(data, "定时发布数据");
    },
    // 发布
    sumbit() {
      if (this.contentLen == 0) {
        return this.$util.Tips({
          title: "内容不能为空",
        });
      }
      if (this.uploadShow) {
        this.getUploadImageList();
      }
      if (this.voteContent) {
        console.log(this.voteContent, "投票数据");
      }
      if (this.scheduleShow) {
        this.getScheduleContent();
      }
      let reg = new RegExp(/\n/g);
      this.getContent = this.content.replace(reg, "<br/>");
      this.$nextTick(() => {
        this.$inputbox.innerHTML = null;
        this.contentLen = this.countLen();
      });
      console.log(this.getContent, "文本框内容");
    },
    inputBoxFocus() {
      if (this.$inputbox) {
        this.$inputbox.focus();
      }
    },
    // 打开表情框
    openEmoji() {
      if (this.emojiBoxShow) {
        this.closeEmoji();
        return;
      }
      this.inputBoxFocus();
      this.emojiBoxShow = true;
      this.documentAddEventListen("click", () => {
        this.closeEmoji();
        this.inputBoxFocus();
      });
    },
    // 关闭表情框
    closeEmoji() {
      this.emojiBoxShow = false;
      this.documentRemoveEventListen("click", this.docCB);
    },
    // 输入框光标定向
    setRange(node, offset) {
      if (!node) return;
      if (offset < 0) offset = 0;
      let range = document.createRange();
      range.selectNodeContents(node);
      range.setStart(node, offset);
      range.setEnd(node, offset);
      range.collapse(false);
      let sel = window.getSelection();
      sel.removeAllRanges();
      sel.addRange(range);
      return sel;
    },
    // 监视输入框丢失焦点
    inputblur() {
      this.closeAt();
    },
    // 获取艾特的对象
    getUserSelect() {
      this.$bus.$on("getUserSelect", (data) => {
        // console.log(data);
        // 将艾特到光标位置的内容替换成艾特的对象
        let range = getSelection().getRangeAt(0);
        let { startContainer, startOffset } = range;
        let atContent = startContainer.data;
        let docF = document.createDocumentFragment();
        let textstart = atContent.slice(0, atContent.indexOf("@"));
        let linkContent = `@${data.uname} `;
        let textend = atContent.slice(startOffset);
        if (!/\n$/.test(textend)) {
          textend += "\n";
        }
        let startNode = document.createTextNode(textstart);
        let endNode = document.createTextNode(textend);
        let linkNode = document.createElement("a");
        linkNode.href = `//space.bilibili.com/${data.uid}/dynamic`;
        linkNode.target = `_blank`;
        linkNode.className = `dynamic_link`;
        linkNode.style.cursor = `pointer`;
        linkNode.style.color = `rgb(0, 161, 214)`;
        linkNode.contentEditable = `false`;
        linkNode.innerText = linkContent;
        docF.appendChild(startNode);
        docF.appendChild(linkNode);
        docF.appendChild(endNode);
        startContainer.parentNode.replaceChild(docF, startContainer);
        this.setRange(endNode, 0);
        this.$nextTick(() => {
          this.content = this.$inputbox.innerHTML;
          this.contentLen = this.countLen();
        });
      });
    },
    // 监视输入框按键抬起
    inputkeyup() {
      this.getAtPosition();
    },
    // 监视输入框被点击
    inputclick() {
      this.getAtPosition();
    },
    // 计算艾特列表的位置
    getAtPosition() {
      /**
       * 1、获取艾特列表是否为打开状态
       * 2、没有打开则返回
       * 3、打开则获取当前光标位置，并返回
       */
      let { scrollTop, scrollLeft } = document.documentElement;
      let range = getSelection().getRangeAt(0);
      let { startContainer, startOffset } = range;
      let rectList = range.getClientRects();
      if (startContainer && startContainer instanceof Text) {
        let textContent = startContainer.data;
        let atReg = new RegExp(/@/);
        if (!textContent) return;
        let at_chatAt = textContent.indexOf("@");
        if (atReg.test(textContent) && startOffset > at_chatAt) {
          // 计算列表位置
          let len = rectList.length;
          let { x, y } = rectList[len - 1];
          this.atPopupLeft = x + scrollLeft - this.sectionOffsetLeft - 16;
          this.atPopupTop = y + scrollTop - this.sectionOffsetTop + 2.4;
          this.atShow = true;
          // 获取@到光标之间的内容
          let atContent = textContent.slice(at_chatAt + 1, startOffset);
          this.$nextTick(() => {
            this.$bus.$emit("getAtContent", atContent);
          });
        } else {
          this.atShow = false;
        }
      } else {
        this.atShow = false;
      }
    },
    // 监视输入框将文字转换为表情
    change() {
      if (this.inputType) return; //判断是否为输入法输入
      //开始输入换行导致内容计数出错
      // console.log(this.$inputbox.innerHTML == '‍\n\n')
      if (/^\n\n/.test(this.$inputbox.innerHTML)) {
        this.$inputbox.innerHTML = null;
        this.contentLen = this.countLen();
        return;
      }
      let range = getSelection().getRangeAt(0); //获取光标位置
      let contentNode = range.commonAncestorContainer; //获取光标所在的文本节点
      let content = range.commonAncestorContainer.data;
      let contentLen = content?.length || 0;
      let offset = range.endOffset;
      let willTransform = false; //用于判断是否需要渲染
      // 对内容进行表情转换
      let expressionReg = new RegExp(/(\[[\u4e00-\u9fa5a-zA-Z0-9_]+\])+?/g); //表情正则
      let lastNode = null;
      let lastNodeLen = 0;
      let documentF = document.createDocumentFragment(); //创建缓存节点，减少渲染
      if (
        contentNode instanceof Text &&
        contentNode.data &&
        contentNode.data.search(expressionReg) != -1
      ) {
        // 存在符合'[中文]'的文本节点
        let strdataarr = content.split(expressionReg); //将文本进行分割
        strdataarr.forEach((item) => {
          //将符合的表情替换成图标标签，其余则创建文本节点
          if (expressionReg.test(item)) {
            expressionReg.lastIndex = 0;
            let expression = this.transform(item); //返回查找到的表情对象或者原内容
            let text = null; //预备的文本节点
            if (expression === item) {
              //如果返回的是原字符串，则未找到匹配表情
              if (lastNode instanceof Text) {
                // 如果上一个节点是文本，则将两个节点合并
                text = document.createTextNode(item);
                lastNode = this.normalizeNode(lastNode, text); //合并节点
                lastNodeLen = lastNode.data.length;
              }
            } else {
              lastNode = expression;
              lastNodeLen = 0;
              willTransform = true;
            }
            documentF.appendChild(lastNode);
          } else {
            // a[藏]b[藏狐]c[糊]d
            // 如果不是表情文本，则为一般文本
            let text = document.createTextNode(item);
            if (lastNode instanceof Text) {
              // 如果上一个节点是文本类型，则上一个文本节点是未找到匹配表情的文本
              lastNode = this.normalizeNode(lastNode, text); //合并节点
              lastNodeLen = lastNode.data.length;
            } else {
              lastNode = text;
              lastNodeLen = item.length;
            }
            documentF.appendChild(lastNode);
          }
        });
      }
      // 只有出现匹配表情才进行表情文本替换
      if (willTransform) {
        contentNode.parentNode.replaceChild(documentF, contentNode); //文本节点替换
        if (lastNode) {
          // 将光标设置为最后一个节点
          if (contentLen - offset > 0) {
            this.setRange(lastNode, lastNodeLen - contentLen + offset);
          } else {
            this.setRange(lastNode, lastNodeLen);
          }
        }
      }
      this.$inputbox.normalize(); //去除空文本节点，并连接相邻文本节点，防止图片后的文字分行
      this.$nextTick(() => {
        this.content = this.$inputbox.innerHTML;
        this.contentLen = this.countLen();
        this.getCloudTopic();
      });
    },
    // 中文等输入法输入开始
    compositionstart() {
      this.inputType = true;
    },
    // 中文等输入法输入结束
    compositionend() {
      this.inputType = false;
      this.$nextTick(() => {
        this.content = this.$inputbox.innerHTML;
        this.contentLen = this.countLen();
        this.getCloudTopic();
      });
    },
    // 用于翻译表情
    transform(content) {
      if (!content) return;
      if (this.emojiList == null) {
        // 发送网络请求
      } else {
        for (let list of this.emojiList) {
          let { emojis } = list;
          for (let emoji of emojis)
            if (emoji.title === content) {
              let expression = document.createElement("img");
              expression.src = emoji.imgUrl;
              expression.alt = emoji.title;
              expression.style.margin = `-1px 1px 0px`;
              expression.style.display = `inline-block`;
              expression.style.width = `20px`;
              expression.style.height = `20px`;
              expression.style["vertical-align"] = `text-bottom`;
              return expression;
            }
        }
      }
      return content;
    },
    // 连接两个节点
    normalizeNode(firstNode, secondNode) {
      if (!firstNode) return;
      if (!secondNode) return;
      let temporaryNode = document.createDocumentFragment(); //创建一个临时节点
      temporaryNode.appendChild(firstNode);
      temporaryNode.appendChild(secondNode);
      temporaryNode.normalize(); //将两个文本节点合并
      return temporaryNode.childNodes[0];
    },
    // 点击插入表情
    inputEmoji(emojiObj) {
      this.inputBoxFocus();
      let emoji;
      if (emojiObj.text) {
        emoji = document.createTextNode(emojiObj.text);
      } else {
        emoji = document.createElement("img");
        emoji.src = emojiObj.imgUrl;
        emoji.alt = emojiObj.alt;
        emoji.style.margin = `-1px 1px 0px`;
        emoji.style.display = `inline-block`;
        emoji.style.width = `20px`;
        emoji.style.height = `20px`;
        emoji.style["vertical-align"] = `text-bottom`;
      }
      let position = window.getSelection().getRangeAt(0); //获取光标的位置
      let { startContainer, startOffset, endContainer, endOffset } = position;
      let documentF = document.createDocumentFragment(); //创建虚拟节点
      if (startContainer == endContainer && startOffset == endOffset) {
        // 情况0、直接插入
        position.insertNode(emoji); //插入内容
        position.collapse(false); //防止插入后选中
      } else if (
        startContainer == endContainer &&
        startOffset != endOffset &&
        startContainer instanceof Text
      ) {
        // 情况1：替换内容为一个纯文本节点
        let content = startContainer.data; //获取节点文本内容
        let startNode = document.createTextNode(content.slice(0, startOffset));
        documentF.appendChild(startNode);
        documentF.appendChild(emoji);
        let endNode = document.createTextNode(
          content.slice(endOffset, content.length)
        );
        documentF.appendChild(endNode); //将选区内容替换成表情节点
        startContainer.parentNode.replaceChild(documentF, startContainer); //将选区所在的文本节点替换成渲染后的虚拟节点
        this.setRange(endNode, 0); //光标重定向
      } else {
        // 情况2、选区包含表情节点
        let startIndex, endIndex;
        let startText, endText;
        for (let [index, item] of Object.entries(this.$inputbox.childNodes)) {
          // 获取涉及到的节点下标
          if (startContainer instanceof Text) {
            // 如果开始位置时文本节点，需要找到文本节点的下标，并获取文本节点的起始位置
            if (item === startContainer) {
              startIndex = index;
              startText = startOffset;
            }
          } else {
            // 如果开始位置时表情节点，则直接获取光标位置-1
            startIndex = startOffset;
          }
          if (endContainer instanceof Text) {
            // 如果结束位置时文本节点，需要找到文本节点的下标，并获取文本节点的结束位置
            if (item === endContainer) {
              endIndex = index;
              endText = endOffset;
            }
          } else {
            // 如果开结束置时表情节点，则直接获取光标位置-1
            endIndex = endOffset;
          }
          if (endIndex) {
            break;
          }
        }
        if (startText == undefined && endText == undefined) {
          // 如果开始文本节点起始位置为undefined，则光标一定位于表情左侧
          // 如果结束文本节点起始位置为undefined，则光标一定位于表情右侧
          for (let [index, item] of Object.entries(this.$inputbox.childNodes)) {
            if (index >= startIndex && index < endIndex) {
              item.parentNode.removeChild(item); //移除包含的节点
            }
          }
          // 插入替换的表情节点
          position.insertNode(emoji); //插入内容
          position.collapse(false); //防止插入后选中
        } else {
          // 开头或结尾是文本节点
          let textContent_start,
            textContent_end,
            TEXTNODE_START,
            TEXTNODE_END,
            startNode,
            endNode;
          let replaceDOCF = document.createDocumentFragment(); // 创建虚拟节点
          if (startText >= 0 && endText == undefined) {
            // 如果开头为文本节点，结尾是表情节点
            for (let [index, item] of Object.entries(
              this.$inputbox.childNodes
            )) {
              if (index == startIndex) {
                startNode = item;
                textContent_start = item.data.slice(0, startText); //获取文本节点内容
                TEXTNODE_START = document.createTextNode(textContent_start); //创建文本节点
                replaceDOCF.appendChild(TEXTNODE_START);
                replaceDOCF.appendChild(emoji);
              }
              if (index > startIndex && index < endIndex) {
                item.parentNode.removeChild(item); //移除包含的节点
              }
              if (index >= endIndex) {
                break;
              }
            }
            startNode.parentNode.replaceChild(replaceDOCF, startNode);
            if (textContent_start) {
              this.setRange(this.$inputbox, startIndex + 2);
            } else {
              this.setRange(this.$inputbox, startIndex + 1);
            }
          } else if (startText == undefined && endText >= 0) {
            // 如果开头为表情，结尾是文本节点
            for (let [index, item] of Object.entries(
              this.$inputbox.childNodes
            )) {
              if (index >= startIndex && index < endIndex) {
                item.parentNode.removeChild(item); //移除包含的节点
              }
              if (index == endIndex) {
                endNode = item;
                textContent_end = item.data.slice(endText); //获取文本节点内容
                TEXTNODE_END = document.createTextNode(textContent_end); //创建文本节点
                replaceDOCF.appendChild(emoji);
                replaceDOCF.appendChild(TEXTNODE_END);
              }
              if (index > endIndex) {
                break;
              }
            }
            endNode.parentNode.replaceChild(replaceDOCF, endNode);
            this.setRange(this.$inputbox, startIndex + 1);
          } else if ((startText >= 0, endText >= 0)) {
            // 开头和结尾都是文本节点
            for (let [index, item] of Object.entries(
              this.$inputbox.childNodes
            )) {
              if (index == startIndex) {
                startNode = item;
                textContent_start = item.data.slice(0, startText); //获取文本节点内容
                TEXTNODE_START = document.createTextNode(textContent_start); //创建文本节点
                replaceDOCF.appendChild(TEXTNODE_START);
              } else if (index > startIndex && index < endIndex) {
                item.parentNode.removeChild(item);
              }
              if (index == endIndex) {
                endNode = item;
                textContent_end = item.data.slice(endText); //获取文本节点内容
                TEXTNODE_END = document.createTextNode(textContent_end); //创建文本节点
                replaceDOCF.appendChild(emoji);
                replaceDOCF.appendChild(TEXTNODE_END);
                item.parentNode.removeChild(item);
              }
            }
            startNode.parentNode.replaceChild(replaceDOCF, startNode);
            if (textContent_start) {
              this.setRange(this.$inputbox, startIndex + 2);
            } else {
              this.setRange(this.$inputbox, startIndex + 1);
            }
          }
        }
      }
      this.$inputbox.normalize();
      this.$nextTick(() => {
        this.content = this.$inputbox.innerHTML;
        this.contentLen = this.countLen();
      });
    },
    // 文字计数
    countLen() {
      this.hasVote = false; //默认不存在投票
      let childrenNode = this.$inputbox?.childNodes;
      let imgLen = 0;
      let textLen = this.$inputbox?.innerText?.replace(/\n/g, "")?.length;
      // console.log(childrenNode)
      for (let [index, node] of Object.entries(childrenNode)) {
        if (node.nodeName == "A") {
          textLen -= 2;
        } else if (node.nodeName == "IMG") {
          imgLen++;
        } else if (node.nodeName == "SPAN") {
          this.hasVote = true;
        } else if (node.nodeName == "#text") {
          let nextEle = node.nextElementSibling;
          if (
            nextEle &&
            (nextEle.nodeName == "A" || nextEle.nodeName == "SPAN")
          ) {
            if (node.textContent.slice(-2) == "\n\n") {
              node.textContent = node.textContent.replace(/\n$/, "");
              this.setRange(node, node.textContent.length - 1);
            }
          } else if (nextEle && nextEle.nodeName == "IMG") {
          } else if (node.textContent && !/\n$/.test(node.textContent)) {
            node.textContent += "\n";
            this.setRange(node, node.textContent.length - 1);
          }
        }
      }
      // 如果不存在投票
      if (!this.hasVote && this.voteContent) {
        // 清除投票内容
        this.voteContent = null;
        this.$voteTitle = null;
      }
      return imgLen + textLen;
    },
    // 监视内容是否为空
    inputZWJ() {
      if (!this.content) {
        // this.content = " ‍\n";
        // this.$inputbox.innerHTML = this.content;
      }
    },
  },
  computed: {
    canScroll() {
      return this.actExpressionList.length > 18;
    },
  },
  filters: {
    dateFilter(dateStr) {
      let dateArr = dateStr.split("-");
      let year = dateArr[0];
      let month = dateArr[1];
      let day = dateArr[2];
      let nowTime = new Date();
      let nowYear = nowTime.getFullYear();
      let nowMonth = nowTime.getMonth() + 1;
      let nowDay = nowTime.getDate();
      let timeNum =
        new Date(year, month, day).getTime() -
        new Date(nowYear, nowMonth, nowDay).getTime();
      if (timeNum == 86400000) {
        return "明天";
      } else if (timeNum < 86400000) {
        return "今天";
      } else {
        if (month <= 9) {
          month = `0${month}`;
        }
        if (day <= 9) day = `0${day}`;
        return `${month}-${day}`;
      }
    },
    hourFilter(hourStr) {
      return hourStr.length < 2 ? `0${hourStr}` : hourStr;
    },
    minuteFilter(minuteStr) {
      return minuteStr.length < 2 ? `0${minuteStr}` : minuteStr;
    },
  },
};
</script>

<style lang="scss">
.emojiBox-leave {
  opacity: 1;
  transform: translateY(0);
}
.emojiBox-leave-to {
  opacity: 0;
  transform: translateY(-20px);
}
.emojiBox-leave-active {
  transition: all 0.3s;
}
.bulletin-enter {
  opacity: 0;
  transform: translateX(30px);
}
.bulletin-leave-to {
  opacity: 0;
  transform: translateX(-30px);
}
.bulletin-enter-to,
.bulletin-leave {
  opacity: 1;
}
.bulletin-enter-active,
.bulletin-leave-active {
  transition: all 0.3s;
}

.vote-enter,
.vote-leave-to {
  opacity: 0;
  top: -20px;
}
.vote-enter-to,
.vote-leave {
  opacity: 1;
  top: 30;
}
.vote-enter-active,
.vote-leave-active {
  transition: all 0.3s;
}
.settings-enter,
.settings-leave-to {
  opacity: 0;
  transform: translateY(-20px);
}
.settings-enter-to,
.settings-leave {
  opacity: 1;
  transform: translateY(0);
}
.settings-enter-active,
.settings-leave-active {
  transition: all 0.3s;
}

.schedule-enter,
.schedule-leave-to {
  height: 0;
  overflow: hidden;
}
.schedule-leave,
.schedule-enter-to {
  height: 54px;
  overflow: hidden;
}
.schedule-enter-active,
.schedule-leave-active {
  transition: all 0.3s ease;
}

.layer-enter,
.layer-leave-to {
  opacity: 0;
  top: 8px;
}
.layer-leave,
.layer-enter-to {
  opacity: 1;
  top: 28px;
}
.layer-enter-active,
.layer-leave-active {
  transition: all 0.3s ease;
}
* {
  list-style: none;
  padding: 0;
  margin: 0;
  .static_popup {
    display: inline-block;
    position: relative;
    background-color: #fff;
    border: 1px solid #e5e9ef;
    border-radius: 8px;
    box-shadow: 0 3px 5px rgba(0, 0, 0, 0.17);
    opacity: 1;
    margin-top: 0;
    z-index: 20;
  }
  .common_font {
    font-family: Helvetica Neue, Helvetica, Arial, Microsoft Yahei,
      Hiragino Sans GB, Heiti SC, WenQuanYi Micro Hei, sans-serif;
    font-size: 14px;
  }
}
.section_block {
  font-family: Helvetica Neue, Helvetica, Arial, Microsoft Yahei,
    Hiragino Sans GB, Heiti SC, WenQuanYi Micro Hei, sans-serif;
  width: 632px;
  padding: 16px;
  background-color: #fff;
  border-radius: 4px;
  position: relative;
  margin-bottom: 8px;
  z-index: 15;
  box-sizing: border-box;
  .publish_block {
    position: relative;
    .new_topic {
      margin-bottom: 8px;
      .topic_selector {
        width: 100%;
        height: 24px;
        font-family: PingFang SC;
        font-style: normal;
        position: relative;
        display: flex;
        flex-direction: row;
        .topic_selector_desk {
          width: 100%;
          display: flex;
          align-items: center;
          -webkit-box-align: center;
          .topic_selector_search {
            .topic_search {
              width: 96px;
              flex-shrink: 0;
              height: 24px;
              position: relative;
              .topic_search_popover {
                background-color: #f6f7f8;
                border: 1px solid #f6f7f8;
                border-radius: 15px;
                box-sizing: border-box;
                display: flex;
                -webkit-box-orient: vertical;
                -webkit-box-direction: normal;
                display: flex;
                flex-direction: column;
                position: absolute;
                left: 0;
                top: 0;
                width: 100%;
                height: 100%;
                z-index: 11;
                transition: all 0.2s linear 0s;
                &.active {
                  background-color: #fff;
                  border-color: #e5e9ef;
                  border-radius: 8px;
                  box-shadow: 0 11px 12px rgba(106, 115, 133, 0.3);
                  box-sizing: border-box;
                  width: 360px;
                  height: 320px;
                  z-index: 15;
                  transition: all 0.2s linear 0s;
                  .topic_search_input {
                    background-color: #f1f2f3;
                    border-radius: 15px;
                    height: 32px;
                    margin: 16px 16px 8px;
                    width: 328px;
                    box-sizing: border-box;
                    .icon-sousuo {
                      color: #9499a0;
                      font-size: 14px;
                      margin-right: 4px;
                    }
                    .topic_search_input_inner {
                      width: 100%;
                      background-color: inherit;
                      color: #18191c;
                      border: none;
                      height: 20px;
                      outline: none;
                      font-size: 12px;
                    }
                  }
                }
                .topic_search_input {
                  display: flex;
                  flex-direction: row;
                  align-items: center;
                  height: 22px;
                  flex-shrink: 0;
                  width: 100%;
                  padding: 0 10px 0 8px;
                  transition: width 0.2s linear 0s;
                  .icon-label {
                    color: #9499a0;
                    font-size: 14px;
                    margin-right: 4px;
                  }
                  .topic_search_input_text {
                    color: #9499a0;
                    font-size: 14px;
                    cursor: text;
                    user-select: none;
                    flex-shrink: 0;
                  }
                }
                .topic_search_result {
                  display: flex;
                  flex-direction: column;
                  -webkit-box-flex: 1;
                  -webkit-box-orient: vertical;
                  -webkit-box-direction: normal;
                  overflow: auto;
                  padding: 0 8px;
                  .topic_search_list {
                    flex: 1;
                    -webkit-box-flex: 1;
                    .topic_item {
                      .topic_item_cloud {
                        padding: 10px 8px;
                        border-radius: 4px;
                        user-select: none;
                        cursor: pointer;
                        position: relative;
                        &:hover {
                          background-color: #f6f7f8;
                        }
                        &.selected {
                          background-color: #f6f7f8;
                        }
                        .icon-label {
                          position: absolute;
                          left: 8px;
                          top: 12px;
                          color: #008ac5;
                        }
                        .topic_item_cloud_info {
                          padding-left: 20px;
                          box-sizing: border-box;
                          width: 100%;
                          .topic_item_cloud_title {
                            display: flex;
                            align-items: center;
                            height: 20px;
                            .topic_item_cloud_name {
                              color: #18191c;
                              font-size: 14px;
                              max-width: calc(100% - 38px);
                              overflow: hidden;
                              text-overflow: ellipsis;
                              white-space: nowrap;
                              &.selected {
                                color: #008ac5;
                              }
                            }
                          }
                          .topic_item_cloud_desc {
                            color: #9499a0;
                            font-size: 12px;
                            line-height: 17px;
                            margin-top: 2px;
                            overflow: hidden;
                            text-overflow: ellipsis;
                            white-space: nowrap;
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
          .topic_selector_rcmd {
            display: flex;
            flex-direction: row;
            align-items: center;
            box-sizing: border-box;
            max-width: calc(100% - 96px);
            padding-left: 8px;
            .topic_selector_rcmd_default {
              display: flex;
              flex: 1;
              align-items: center;
              overflow: hidden;
              .topic_item {
                .topic_item_stela {
                  display: flex;
                  align-items: center;
                  background-color: #ecfafe;
                  border-radius: 15px;
                  box-sizing: border-box;
                  cursor: pointer;
                  height: 24px;
                  padding: 0 12px 0 8px;
                  user-select: none;
                  transition: opacity 0.2s;
                  .iconfont {
                    color: #008ac5;
                    flex-shrink: 0;
                    margin-right: 4px;
                    font-size: 14px;
                  }
                  .topic_item_stela_name {
                    color: #008ac5;
                    font-size: 14px;
                    white-space: nowrap;
                  }
                }
              }
            }
            .topic_selector_rcmd_more {
              flex-shrink: 0;
              padding-left: 8px;
              .topic_rcmd_more {
                flex-shrink: 0;
                height: 24px;
                width: 24px;
                position: relative;
                .topic_rcmd_more_popover {
                  border: 1px solid #ecfafe;
                  border-radius: 15px;
                  box-sizing: border-box;
                  display: flex;
                  flex-direction: column;
                  height: 100%;
                  width: 100%;
                  position: absolute;
                  top: 0;
                  left: 0;
                  overflow: hidden;
                  transform: translateZ(0);
                  transition: all 0.3s;
                  z-index: 10;
                  &.hover {
                    height: 118px;
                    width: 260px;
                    background-color: #fff;
                    border: 1px solid #e5e9ef;
                    border-radius: 8px;
                    box-shadow: 0 11px 12px rgba(106, 115, 133, 0.3);
                    box-sizing: border-box;
                    overflow-y: auto;
                    padding: 4px 0 8px 4px;
                    transform: translate3d(-4px, -4px, 0);
                    .topic_rcmd_more_action {
                      background-color: transparent !important;
                      color: #9499a0 !important;
                      transform: rotate(180deg);
                    }
                  }
                  .topic_rcmd_more_bar {
                    display: flex;
                    .topic_rcmd_more_action {
                      display: flex;
                      align-items: center;
                      justify-content: center;
                      background-color: #ecfafe;
                      border-radius: 50%;
                      color: #008ac5;
                      flex-shrink: 0;
                      width: 22px;
                      height: 22px;
                      transition: 0.3s;
                      user-select: none;
                      .topic_rcmd_more_action_icon {
                        width: 10px;
                      }
                    }
                    .topic_rcmd_more_text {
                      display: flex;
                      align-items: center;
                      flex-shrink: 0;
                      font-size: 12px;
                      color: #9499a0;
                      height: 24px;
                      padding-left: 4px;
                    }
                  }
                  .topic_rcmd_more_item {
                    padding: 0 16px 0 20px;
                    .topic_item {
                      .topic_item_cloud {
                        border-radius: 4px;
                        cursor: pointer;
                        position: relative;
                        padding: 10px 8px;
                        user-select: none;
                        .icon-label {
                          color: #008ac5;
                          display: inline-block;
                          position: absolute;
                          left: 8px;
                          top: 12px;
                        }
                        .topic_item_cloud_info {
                          box-sizing: border-box;
                          padding-left: 20px;
                          width: 100%;
                          .topic_item_cloud_info_title {
                            display: flex;
                            align-items: center;
                            height: 20px;
                            .topic_item_cloud_info_name {
                              color: #18191c;
                              font-size: 14px;
                              max-width: calc(100%-38px);
                              overflow: hidden;
                              text-overflow: ellipsis;
                              white-space: nowrap;
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
        .topic_selector_bulletin {
          background-color: #fff;
          height: 100%;
          width: 100%;
          position: absolute;
          z-index: 11;
          display: flex;
          align-items: center;
          .topic_selector_bulletin_item {
            margin-right: 8px;
            .topic_item {
              .topic_item_normal {
                height: 20px;
                display: flex;
                align-items: center;
                border-radius: 2px;
                cursor: pointer;
                user-select: none;
                &:hover {
                  background-color: #ecfafe;
                }
                .topic_item_normal_name {
                  font-size: 14px;
                  color: #008ac5;
                }
                .icon-label {
                  font-size: 14px;
                  color: #008ac5;
                  margin-right: 4px;
                }
              }
            }
          }
          .topic_selector_bulletin_clear {
            display: flex;
            align-items: center;
            justify-content: center;
            background-color: #dff6fd;
            border-radius: 50%;
            height: 14px;
            width: 14px;
            user-select: none;
            cursor: pointer;
            .icon-guanbi {
              color: #008ac5;
              transform: scale3d(0.5, 0.5, 1);
              font-size: 16px;
            }
          }
        }
      }
    }
    .editorbox {
      .editor {
        position: relative;
        overflow-x: hidden;
        overflow-y: auto;
        .core_style {
          width: 100%;
          line-height: 22px;
          min-height: 22px;
          max-height: 300px;
          letter-spacing: 1px; //文字间距
          color: #222;
          background-color: #fff;
          font-size: 14px;
          box-sizing: border-box;
          white-space: pre-wrap;
          vertical-align: baseline; //文字对齐
          word-break: break-word;
          word-wrap: break-word;
          outline: none;
          border-radius: 4px;
          -webkit-user-modify: read-write-plaintext-only; //防止换行自动插入div
          // /deep/ scoped穿透
          & /deep/ a {
            text-decoration: none;
            outline: none;
          }
          & /deep/ .dynamic_link {
            border-radius: 4px;
            user-select: text;
            &:hover {
              background-color: #dde2eb;
            }
            & .vote_icon {
              vertical-align: middle;
              display: inline-block;
              background-image: url("/static/video/投票.png");
              background-repeat: no-repeat;
              background-size: 14px 14px;
            }
            & .vote_btn {
              background-position: center center;
              width: 14px;
              height: 14px;
            }
          }
        }
        &::-webkit-scrollbar {
          width: 5px;
        }
        &::-webkit-scrollbar-track {
          background-color: #fff;
        }
        &::-webkit-scrollbar-thumb {
          background-color: rgb(230, 230, 230);
        }
      }
      .placeholder-shown::before {
        content: attr(placeholder);
        position: absolute;
        font-size: 14px;
        color: #99a2aa;
        line-height: 22px;
        letter-spacing: 1px;
        pointer-events: none;
      }
      .publish_tip {
        font-size: 12px;
        color: #ccd0d7;
        pointer-events: none;
        transform: translateY(6px);
      }
      .attach_card {
        padding-top: 32px;
        .shop_panel {
          width: 600px;
          margin-top: 12px;
          box-sizing: border-box;
          .shop_list {
            width: 100%;
            background-color: #f4f7f9;
            border-radius: 4px;
            display: flex;
            justify-content: center;
            align-items: center;
            overflow: auto;
            position: relative;
            &.reserve {
              padding: 10px 12px;
            }
            .shop_desc {
              display: flex;
              justify-content: flex-start;
              flex: 1;
              position: relative;
              width: 100%;
              .desc_box {
                flex: 1;
                overflow: hidden;
                outline: none;
                text-decoration: none;
                cursor: default;
                .title {
                  overflow: hidden;
                  text-overflow: ellipsis;
                  word-break: break-word;
                  font-size: 14px;
                  line-height: 19px;
                  color: #212121;
                  margin-bottom: 0;
                  margin-right: 12px;
                }
                .multi_line {
                  white-space: unset;
                  display: flex;
                  flex-grow: 1;
                  flex-direction: column;
                  max-height: unset;
                }
                .sub_title {
                  display: flex;
                  flex-direction: column;
                  overflow: hidden;
                  text-overflow: ellipsis;
                  word-break: break-word;
                  line-height: 16px;
                  height: 16px;
                  font-size: 12px;
                  margin-right: 36px;
                  &.reserve {
                    color: #999;
                    margin-top: 5px;
                    span {
                      display: inline-block;
                      flex-grow: 1;
                    }
                  }
                }
              }
            }
            .delete_btn {
              cursor: pointer;
              position: absolute;
              height: 14px;
              width: 14px;
              right: 6px;
              top: 6px;
              line-height: 14px;
              text-align: center;
              font-size: 14px;
              color: #99a2aa;
            }
          }
        }
      }
    }
    .toolbar {
      display: flex;
      flex-direction: row;
      align-items: center;
      justify-content: space-between;
      margin-top: 12px;
      .toolbar_box {
        width: 100%;
        display: flex;
        flex-direction: row;
        .toolbar_item {
          &:not(:first-child) {
            margin-left: 20px;
          }
          .box_toggle {
            cursor: pointer;
            .iconfont {
              font-size: 24px;
              color: #999999;
              &:hover {
                color: #00a1d6;
              }
              &.on {
                color: #00a1d6;
              }
            }
          }
        }
        .emoji_box,
        .pic_box,
        .vote_box,
        .schedule_box,
        .reserve_box {
          position: relative;
        }
      }
      .publish_launcher {
        display: flex;
        flex-direction: row;
        align-items: center;
        justify-content: center;
        .indicator {
          margin-right: 20px;
          color: #99a2aa;
          font-size: 14px;
          position: relative;
          &::after {
            content: "|";
            position: absolute;
            right: -12px;
            top: -1px;
            color: #e5e9ef;
          }
        }
        .comment_setting {
          position: relative;
          outline: none;
          width: 78px;
          .comment_setting_btn {
            font-size: 12px;
            color: #99a2aa;
            letter-spacing: 0;
            cursor: pointer;
            user-select: none;
            .icon-zhankai {
              font-size: 16px;
              transition: transform 0.2s linear 0s;
              display: inline-block; //设置行内块才能开启变形？
              &.active {
                transform: rotate(-180deg);
              }
            }
          }
          .settings_panel {
            position: absolute;
            top: 20px;
            right: 12px;
            width: 120px;
            z-index: 2;
            border: 1px solid #e5e9ef;
            box-shadow: 0 11px 12px 0 rgba(106, 115, 133, 0.3);
            border-radius: 4px;
            display: flex;
            flex-direction: column;
            background-color: #fff;
            .settings_panel_option {
              height: 36px;
              padding-left: 12px;
              line-height: 36px;
              font-size: 12px;
              color: #222;
              letter-spacing: 0;
              cursor: pointer;
              &:hover {
                background-color: #f4f7f9;
              }
              &.active {
                color: #00a1d6;
              }
            }
          }
        }
        .publish_btn {
          width: 70px;
          height: 32px;
          outline: none;
          background-color: #00a1d6;
          font-size: 13px;
          line-height: 33px;
          color: #fff;
          border: none;
          border-radius: 4px;
          &:hover {
            background-color: #33b4de;
          }
          &.disable {
            opacity: 0.5;
            &:hover {
              background-color: #00a1d6;
            }
          }
        }
      }
    }
  }
}
</style>